#include "cconf.h"
#include "error.h"
#include "config_type.h"

#include <string.h>

/**
 * return a string showing the config error
 */

char * cconf_error_str(cconf_error_t error)
{
	static char str[512] = "no error";
	
	switch (error)
    {
		case CCONF_ERROR_NOMEM:
			sprintf(str, "out of memory"); 
			break;
		case CCONF_ERROR_BAD_FILE:
			sprintf(str, "couldn't read config file"); 
			break;
		case CCONF_ERROR_ENTRY_EXISTS:
			sprintf(str, "entry already exists in configuration");
			break;
		case CCONF_ERROR_NO_SUCH_ENTRY:
			sprintf(str, "no such configuration entry"); 
			break;
        case CCONF_ERROR_FAILED_SANITY:
            sprintf(str, "file failed sanity check");
            break;
        case CCONF_ERROR_INVALID:
            sprintf(str, "failed validity check");
            break;
		case CCONF_ERROR_NO_ERROR:
			sprintf(str, "no error"); 
			break;
		default:
			sprintf(str, "unknown error"); 
			break;
	}
		
	return str;
}

cconf_error_stack_t * cconf_pop_error(cconf_t * c)
{
    cconf_error_stack_t * e = c->errors;
    
    if (NULL == c->errors)
        return NULL;
    
    c->errors = e->next;
    e->next = NULL;
    return e;
}


int cconf_push_error(cconf_t * c, char * error, int dup, int bottom)
{
    cconf_error_stack_t * e = calloc(1, sizeof(cconf_error_stack_t));
    
    if (NULL == e)
        return CCONF_ERROR_NOMEM;
    
    e->error = dup ? strdup(error): error;
    e->count = c->errors ? c->errors->count + 1 : 1;
    e->level = bottom == 0 ? 0 : c->errors ? c->errors->level + 1 : 1;
    e->next = c->errors;
    c->errors = e;
    
    return 0;
}

int cconf_push_error_code(cconf_t * c, cconf_error_t err, int level)
{
    int result = cconf_push_error(c, cconf_error_str(err), 1, level);
    return !result ? err : result;
}
